package structs;

import interfaces.ICard;
import interfaces.IPlayer;

import java.util.ArrayList;

/**
 * @author Abner
 */
public class DeckInformation {

	private Game game;
	private IPlayer ai;
	private Deck deck;

	//Current Hand
	private ICard hand1;
	private ICard hand2;
	private ICard hand3;

	//Deck
	private ArrayList<ICard> highLifeCards;
	private ArrayList<ICard> midLifeCards;
	private ArrayList<ICard> lowLifeCards;
	private ArrayList<ICard> lifeCards;

	private ArrayList<ICard> otherHighCards;
	private ArrayList<ICard> otherMidCards;
	private ArrayList<ICard> otherLowCards;

	private ArrayList<ICard> copaCards;
	private ArrayList<ICard> bastoCards;
	private ArrayList<ICard> espadaCards;
	private ArrayList<ICard> oroCards;

	private ArrayList<ICard> lowBCards;
	private ArrayList<ICard> midBCards;
	private ArrayList<ICard> highBCards;

	private ArrayList<ICard> lowCCards;
	private ArrayList<ICard> midCCards;
	private ArrayList<ICard> highCCards;

	private ArrayList<ICard> lowECards;
	private ArrayList<ICard> midECards;
	private ArrayList<ICard> highECards;

	private ArrayList<ICard> lowOCards;
	private ArrayList<ICard> midOCards;
	private ArrayList<ICard> highOCards;
	private double cardsNotSeen;
	
	private double hand2CardsNotSeen;
	private double hand1CardsNotSeen;
	private double hand3CardsNotSeen;

	private int higherHand1Cards;
	private int higherHand2Cards;
	private int higherHand3Cards;

	
	private ICard[] currentCardsPlayed;
	private int turn;
	private ArrayList<ICard> currentHand = new ArrayList<ICard>();
	



	public DeckInformation(Game game){
		this.game = game;
		deck = this.game.getDeck();
		ai = this.game.getAIPlayer();
		this.hand1CardsNotSeen = 0.0;
		this.hand2CardsNotSeen = 0.0;
		this.hand3CardsNotSeen = 0.0;
		this.cardsNotSeen = 0.0;

		this.highLifeCards = new ArrayList<ICard>();
		this.midLifeCards = new ArrayList<ICard>();
		this.lowLifeCards = new ArrayList<ICard>();
		this.lifeCards = new ArrayList<ICard>();

		this.bastoCards = new ArrayList<ICard>();
		this.copaCards = new ArrayList<ICard>();
		this.espadaCards = new ArrayList<ICard>();
		this.oroCards = new ArrayList<ICard>();

		this.highBCards = new ArrayList<ICard>();
		this.midBCards = new ArrayList<ICard>();
		this.lowBCards = new ArrayList<ICard>();

		this.highCCards = new ArrayList<ICard>();
		this.midCCards = new ArrayList<ICard>();
		this.lowCCards = new ArrayList<ICard>();

		this.highECards = new ArrayList<ICard>();
		this.midECards = new ArrayList<ICard>();
		this.lowECards = new ArrayList<ICard>();

		this.highOCards = new ArrayList<ICard>();
		this.midOCards = new ArrayList<ICard>();
		this.lowOCards = new ArrayList<ICard>();

		this.otherHighCards = new ArrayList<ICard>();
		this.otherMidCards = new ArrayList<ICard>();
		this.otherLowCards = new ArrayList<ICard>();
	}

	public void initializeDeckInfo(){
		
		for(ICard card : deck.getCards())
		{
			if(card.getSuit().equalsIgnoreCase(deck.getLife().getSuit()))
			{
				if(card.getPoints() > 4)
				{
					this.highLifeCards.add(card);
					this.lifeCards.add(card);
				}

				else if(card.getPoints() >0 && card.getPoints() <=4)
				{
					this.midLifeCards.add(card);
					this.lifeCards.add(card);
				}

				else
				{
					this.lowLifeCards.add(card);
					this.lifeCards.add(card);
				}	
			}			

			else
			{
				if(card.getPoints() > 4)
				{
					this.otherHighCards.add(card);
				}

				else if(card.getPoints() >0 && card.getPoints() <=4)
				{
					this.otherMidCards.add(card);
				}

				else
				{
					this.otherLowCards.add(card);
				}	
			}
		}

		for(ICard card : deck.getCards())
		{
			if(card.getSuit().equalsIgnoreCase("b"))
			{
				if(card.getPoints() > 4)
				{
					this.highBCards.add(card);
					this.bastoCards.add(card);
				}

				else if(card.getPoints() >0 && card.getPoints() <=4)
				{
					this.midBCards.add(card);
					this.bastoCards.add(card);
				}

				else
				{
					this.lowBCards.add(card);
					this.bastoCards.add(card);
				}	
			}

			else if(card.getSuit().equalsIgnoreCase("c"))
			{
				if(card.getPoints() > 4)
				{
					this.highCCards.add(card);
					this.copaCards.add(card);
				}

				else if(card.getPoints() >0 && card.getPoints() <=4)
				{
					this.midCCards.add(card);
					this.copaCards.add(card);
				}

				else
				{
					this.lowCCards.add(card);
					this.copaCards.add(card);
				}	
			}

			else if(card.getSuit().equalsIgnoreCase("e"))
			{
				if(card.getPoints() > 4)
				{
					this.highECards.add(card);
					this.espadaCards.add(card);
				}

				else if(card.getPoints() >0 && card.getPoints() <=4)
				{
					this.midECards.add(card);
					this.espadaCards.add(card);
				}

				else
				{
					this.lowECards.add(card);
					this.espadaCards.add(card);
				}	
			}

			else
			{
				if(card.getPoints() > 4)
				{
					this.highOCards.add(card);
					this.oroCards.add(card);
				}

				else if(card.getPoints() >0 && card.getPoints() <=4)
				{
					this.midOCards.add(card);
					this.oroCards.add(card);
				}

				else
				{
					this.lowOCards.add(card);
					this.oroCards.add(card);
				}	
			}
		}
		removeCardFromSuit(deck.getLife());
		removeTeamMateCards();
	}

	public void updateDeckInfo()
	{
		deck = this.game.getDeck();
		this.currentCardsPlayed = this.game.getCurrentCardsPlayed();
		this.turn = this.game.getCurrentHandTurn();
		this.currentHand = this.ai.getCurrentHand();
		
		if(this.game.getRoundNumber()<=8)
		{
			//FIXME
			sortHand(ai.getCurrentHand().get(0),ai.getCurrentHand().get(1),ai.getCurrentHand().get(2));
			this.currentHand = this.ai.getCurrentHand();
			this.hand1 = this.currentHand.get(0);
			this.hand2 = this.currentHand.get(1);
			this.hand3 = this.currentHand.get(2);
		}
		
		else if(this.game.getRoundNumber()==9)
		{
			this.hand1 = this.currentHand.get(0);
			this.hand2 = this.currentHand.get(1);
		}
		
		else
		{
			this.hand1 = this.currentHand.get(0);
		}
		
		removeCurrentCardsPlayed();
		
		this.cardsNotSeen =  bastoCards.size() + oroCards.size() + copaCards.size() + espadaCards.size();
		this.higherHand1Cards = 0;
		this.higherHand2Cards = 0;
		this.higherHand3Cards = 0;

		for(int i=0; i<this.currentHand.size();i++)
		{
			if(ai.getCurrentHand().get(i).getSuit().equalsIgnoreCase(deck.getLife().getSuit()))
			{
				for(ICard card : lifeCards)
				{
					if((card.getPoints() > ai.getCurrentHand().get(i).getPoints())
							|| ((card.getPoints() == 0) && ai.getCurrentHand().get(i).getPoints() == 0)
							&& card.getNumber() > ai.getCurrentHand().get(i).getNumber())
					{
						incHigherHandCards(i,1);
					}
				}
				
				handCardNotSeen(i, lifeCards.size()/1.0);

			}

			else
			{
				if(ai.getCurrentHand().get(i).getSuit().equalsIgnoreCase("b"))
				{
					for(ICard card : bastoCards)
					{
						if((card.getPoints() > ai.getCurrentHand().get(i).getPoints())
								|| ((card.getPoints() == 0) && ai.getCurrentHand().get(i).getPoints() == 0)
								&& card.getNumber() > ai.getCurrentHand().get(i).getNumber())
						{
							incHigherHandCards(i,1);
						}
					}

					incHigherHandCards(i,lifeCards.size());
					handCardNotSeen(i, (bastoCards.size() + lifeCards.size())/1.0);
				}

				else if(ai.getCurrentHand().get(i).getSuit().equalsIgnoreCase("c"))
				{
					for(ICard card : copaCards)
					{
						if((card.getPoints() > ai.getCurrentHand().get(i).getPoints())
								|| ((card.getPoints() == 0) && ai.getCurrentHand().get(i).getPoints() == 0)
								&& card.getNumber() > ai.getCurrentHand().get(i).getNumber())
						{
							incHigherHandCards(i,1);
						}
					}

					incHigherHandCards(i,lifeCards.size());
					handCardNotSeen(i, (copaCards.size() + lifeCards.size())/1.0);
				}

				else if(ai.getCurrentHand().get(i).getSuit().equalsIgnoreCase("e"))
				{
					for(ICard card : espadaCards)
					{
						if((card.getPoints() > ai.getCurrentHand().get(i).getPoints())
								|| ((card.getPoints() == 0) && ai.getCurrentHand().get(i).getPoints() == 0)
								&& card.getNumber() > ai.getCurrentHand().get(i).getNumber())
						{
							incHigherHandCards(i,1);
						}
					}

					incHigherHandCards(i,lifeCards.size());
					handCardNotSeen(i, (espadaCards.size() + lifeCards.size())/1.0);
				}

				else
				{
					for(ICard card : oroCards)
					{
						if((card.getPoints() > ai.getCurrentHand().get(i).getPoints())
								|| ((card.getPoints() == 0) && ai.getCurrentHand().get(i).getPoints() == 0)
								&& card.getNumber() > ai.getCurrentHand().get(i).getNumber())
						{
							incHigherHandCards(i,1);
						}
					}

					incHigherHandCards(i,lifeCards.size());
					handCardNotSeen(i, (oroCards.size() + lifeCards.size())/1.0);
				}
			}
		}
	}



	public void sortHand(ICard h1,ICard h2,ICard h3)
	{
		String h1Suit = "" + h1.getSuit();
		String h2Suit = "" + h2.getSuit();
		String h3Suit = "" + h3.getSuit();

		int h1Points = h1.getPoints();
		int h2Points = h2.getPoints();
		int h3Points = h3.getPoints();

		int h1Number = h1.getNumber();
		int h2Number = h2.getNumber();
		int h3Number = h3.getNumber();

		if((h1Suit.equalsIgnoreCase(deck.getLife().getSuit()) 
				&& !h2Suit.equalsIgnoreCase(deck.getLife().getSuit())) 
				|| (((!h1Suit.equalsIgnoreCase(deck.getLife().getSuit()) 
						&& !h2Suit.equalsIgnoreCase(deck.getLife().getSuit())) 
						|| (h1Suit.equalsIgnoreCase(deck.getLife().getSuit()) 
								&& h2Suit.equalsIgnoreCase(deck.getLife().getSuit()))) 
								&& ((h1Points >= h2Points) 
										|| ((h1Points == 0 && h2Points == 0) 
												&& (h1Number >= h2Number))))) 

		{
			if((h1Suit.equalsIgnoreCase(deck.getLife().getSuit()) 
					&& !h3Suit.equalsIgnoreCase(deck.getLife().getSuit())) 
					|| (((!h1Suit.equalsIgnoreCase(deck.getLife().getSuit()) 
							&& !h3Suit.equalsIgnoreCase(deck.getLife().getSuit())) 
							|| (h1Suit.equalsIgnoreCase(deck.getLife().getSuit()) 
									&& h3Suit.equalsIgnoreCase(deck.getLife().getSuit()))) 
									&& ((h1Points >= h3Points) 
											|| ((h1Points == 0 && h3Points == 0) 
													&& (h1Number >= h3Number))))) 
			{
				if((h2Suit.equalsIgnoreCase(deck.getLife().getSuit()) 
						&& !h3Suit.equalsIgnoreCase(deck.getLife().getSuit())) 
						|| (((!h2Suit.equalsIgnoreCase(deck.getLife().getSuit()) 
								&& !h3Suit.equalsIgnoreCase(deck.getLife().getSuit())) 
								|| (h2Suit.equalsIgnoreCase(deck.getLife().getSuit()) 
										&& h3Suit.equalsIgnoreCase(deck.getLife().getSuit()))) 
										&& ((h2Points >= h3Points) 
												|| ((h2Points == 0 && h3Points == 0) 
														&& (h2Number >= h3Number))))) 
				{
					this.hand3 = h1;
					this.hand2 = h2;
					this.hand1 = h3;
				}

				else
				{
					this.hand3 = h1;
					this.hand2 = h3;
					this.hand1 = h2;
				}
			}

			else
			{
				this.hand3 = h3;
				this.hand2 = h1;
				this.hand1 = h2;
			}
		}

		else
		{
			if((h2Suit.equalsIgnoreCase(deck.getLife().getSuit()) 
					&& !h3Suit.equalsIgnoreCase(deck.getLife().getSuit())) 
					|| (((!h2Suit.equalsIgnoreCase(deck.getLife().getSuit()) 
							&& !h3Suit.equalsIgnoreCase(deck.getLife().getSuit())) 
							|| (h2Suit.equalsIgnoreCase(deck.getLife().getSuit()) 
									&& h3Suit.equalsIgnoreCase(deck.getLife().getSuit()))) 
									&& ((h2Points >= h3Points) 
											|| ((h2Points == 0 && h3Points == 0) 
													&& (h2Number >= h3Number)))))
			{
				if((h1Suit.equalsIgnoreCase(deck.getLife().getSuit()) 
						&& !h3Suit.equalsIgnoreCase(deck.getLife().getSuit())) 
						|| (((!h1Suit.equalsIgnoreCase(deck.getLife().getSuit()) 
								&& !h3Suit.equalsIgnoreCase(deck.getLife().getSuit())) 
								|| (h1Suit.equalsIgnoreCase(deck.getLife().getSuit()) 
										&& h3Suit.equalsIgnoreCase(deck.getLife().getSuit()))) 
										&& ((h1Points >= h3Points) 
												|| ((h1Points == 0 && h3Points == 0) 
														&& (h1Number >= h3Number)))))
				{
					this.hand3 = h2;
					this.hand2 = h1;
					this.hand1 = h3;
				}

				else
				{
					this.hand3 = h2;
					this.hand2 = h3;
					this.hand1 = h1;
				}
			}

			else
			{
				this.hand3 = h3;
				this.hand2 = h2;
				this.hand1 = h1;
			}
		}

		ArrayList<ICard> newHand = new ArrayList<ICard>();

		newHand.add(this.hand1);
		newHand.add(this.hand2);
		newHand.add(this.hand3);

		ai.setCurrentHand(newHand);
	}

	public void removeCardFromSuit(ICard card){
		if(card.getSuit().equalsIgnoreCase(deck.getLife().getSuit()))	
		{
			removeCard(lifeCards,card.getNumber(),card.getSuit());
		}
		
		if(card.getSuit().equalsIgnoreCase("b"))
		{
			removeCard(bastoCards,card.getNumber(),card.getSuit());
		}
		
		else if(card.getSuit().equalsIgnoreCase("c"))
		{
			removeCard(copaCards,card.getNumber(),card.getSuit());
		}
		
		else if(card.getSuit().equalsIgnoreCase("e"))
		{
			removeCard(espadaCards,card.getNumber(),card.getSuit());
		}
		
		else
		{
			removeCard(oroCards,card.getNumber(),card.getSuit());
		}
	
	}
	public ICard removeCard(ArrayList<ICard> cards, int num, String suit) {
		int toDel = 0;
		boolean found = false;

		for(ICard card : cards){
			if(card.getSuit().equalsIgnoreCase(suit) && card.getNumber() == num){
				found = true;
				break;
			}
			toDel++;
		}

		if(found){
			return cards.remove(toDel);
		}

		return null;
	}


	public ArrayList<ICard> getHighLifeCards()
	{
		return highLifeCards;
	}

	public ArrayList<ICard> getMidLifeCards()
	{
		return midLifeCards;
	}

	public ArrayList<ICard> getLowLifeCards()
	{
		return lowLifeCards;
	}

	public ArrayList<ICard> getOtherHighCards()
	{
		return otherHighCards;
	}

	public ArrayList<ICard> getOtherMidCards()
	{
		return otherMidCards;
	}

	public ArrayList<ICard> getOtherLowCards()
	{
		return otherLowCards;
	}

	public ArrayList<ICard> getHighBastoCards()
	{
		return highBCards;
	}

	public ArrayList<ICard> getMidBastoCards()
	{
		return midBCards;
	}

	public ArrayList<ICard> getLowBastoCards()
	{
		return lowBCards;
	}

	public ArrayList<ICard> getHighCopaCards()
	{
		return highCCards;
	}

	public ArrayList<ICard> getMidCopaCards()
	{
		return midCCards;
	}

	public ArrayList<ICard> getLowCopaCards()
	{
		return lowCCards;
	}

	public ArrayList<ICard> getHighEspadaCards()
	{
		return highECards;
	}

	public ArrayList<ICard> getMidEspadaCards()
	{
		return midECards;
	}

	public ArrayList<ICard> getLowEspadaCards()
	{
		return lowECards;
	}

	public ArrayList<ICard> getHighOroCards()
	{
		return highOCards;
	}

	public ArrayList<ICard> getMidOroCards()
	{
		return midOCards;
	}

	public ArrayList<ICard> getLowOroCards()
	{
		return lowOCards;
	}

	public ArrayList<ICard> getCopaCards()
	{
		return copaCards;
	}

	public ArrayList<ICard> getBastoCards()
	{
		return bastoCards;
	}

	public ArrayList<ICard> getOroCards()
	{
		return oroCards;
	}

	public ArrayList<ICard> getEspadaCards()
	{
		return espadaCards;
	}

	public int getHigherHand1Cards()
	{
		return this.higherHand1Cards;
	}

	public int getHigherHand2Cards()
	{
		return this.higherHand2Cards;
	}

	public int getHigherHand3Cards()
	{
		return this.higherHand3Cards;
	}
	
	public double getHand1CardsNotSeen()
	{
		return this.hand1CardsNotSeen;
	}
	
	public double getHand2CardsNotSeen()
	{
		return this.hand2CardsNotSeen;
	}
	
	public double getHand3CardsNotSeen()
	{
		return this.hand3CardsNotSeen;
	}

	public ArrayList<ICard> getLifeCards()
	{
		return lifeCards;
	}

	public void incHigherHandCards(int i,int j) 
	{
		if(i==0)
		{
			higherHand1Cards+= j;
		}
		else if(i==1)
		{
			higherHand2Cards+= j;
		}

		else
		{
			higherHand3Cards+= j;
		}
	}

	public void printCards(ArrayList<ICard> cards)
	{
		System.out.print("Cards: ");
		for(int i=0; i< cards.size(); i++)
		{
			System.out.print(cards.get(i).getNumber()+ cards.get(i).getSuit()+ " ");
		}
		System.out.print("\n");
	}
	
	public void removeCurrentCardsPlayed()
	{
		for(int i=0; i<this.turn;i++)
		{
			removeCardFromSuit(this.currentCardsPlayed[i]);
		}
	}
	
	public void removeTeamMateCards()
	{
		int teamMateHandSize = this.game.getTeamPlayer().getCurrentHand().size();
		for(int i=0; i<teamMateHandSize;i++)
		{
			removeCardFromSuit(this.game.getTeamPlayer().getCurrentHand().get(i));
		}
	}
	
	public double getCardNotSeen()
	{
		return this.cardsNotSeen;
	}
	
	public void handCardNotSeen(int i, double j)
	{
		if(i==0)
		{
			this.hand1CardsNotSeen = j;
		}
		else if(i==1)
		{
			this.hand2CardsNotSeen = j;
		}

		else
		{
			this.hand3CardsNotSeen = j;
		}
	}

}
